::::::::::::::::::::::::::::::::::::::::::::::::::::
::::::::::::::::::::::::::::::::::::::::::::::::::::
Typically, Liberty BASIC programmers write user-defined LB functions with the expectation that the function will return a single value. There are occasions, however, when it would be extremely helpful if a function could return two, three or more values, instead of just a single value.
Fortunately, there is a convenient technique that LB programmers have been using lately to persuade functions to return multiple numeric values. Here's how it works.
TwoValues$ = MyFunction$(x,y,z)
Then define the function elsewhere in your program:
Function MyFunction$(a,b,c) ... end Function
The dollar sign - $ - at the end of the function name tells LB's compiler that this is a string function.
answer1 = ((-1) * b + SQR(b^2 - 4*a*c)) / (2*a) answer2 = ((-1) * b - SQR(b^2 - 4*a*c)) / (2*a)
answer1$ = str$(answer1) answer2$ = str$(answer2)
MyFunction$ = answer1$ + " " + answer2$
MyFunction$ is the variable that is returned to that portion of the program which calls the function. Note that two spaces, " ", are used as the separator string. Because these two spaces separate answer1 and answer2, the two answers can be extracted from the return value by parsing. Parsing can be accomplished by use of Liberty BASIC's built-in word$() and val() functions.
FirstValue = val(word$(TwoValues$, 1)) SecondValue = val(word$(TwoValues$, 2))
That's it! Mission accomplished.
The purpose of persuading a function to return two values is to avoid writing -- and calling -- two separate functions which return a single value each, particularly if the two functions would be nearly identical anyway. Though it may not be true in all cases, the expectation is that use of a single function will be faster despite that fact that the answer must be parsed once the function has done its job.
With speed in mind, I am hypothesizing that efficiency can be gained if the function is called -- and the returned value parsed -- by using the following procedure:
TwoValues$ = MyFunction$(x,y,z) FirstValue = val(word$(TwoValues$, 1)) SecondValue = val(word$(TwoValues$, 2))
In the example above, the return value is stored in TwoValues$, and then the two desired answers are parsed from the return value. Contrast that procedure with this less-efficient one:
FirstValue = val(word$(MyFunction$(x,y,z), 1)) SecondValue = val(word$(MyFunction$(x,y,z), 2))
Note that the second procedure is expected to be less efficient because it calls the function MyFunction$() twice! The second procedure defeats the purpose of writing a function which returns two values, because the program ends up making two function calls anyway.
The speed difference may not be noticeable if the function is not math intensive, or if the function is called very few times in the program anyway. However, if the function is long and complicated, and/or if the function is called thousands of times during program operation, the speed might be noticeable. (See the article discussing ScreenX() and ScreenY() for an example of two math-intensive, nearly-identical functions which are called thousands of times during the creation of 3D wire frame models.)
In Liberty BASIC Newsletter 130, I contributed an article called Projectile Motion in 3D Space. This article discussed the mathematics for calculating the x-, y- and z-coordinates of a projectile at any time, t, given the projectile's launch location, initial angle, and initial velocity.
This set of equations can be made much more usable if we employ the Convert and Concatenate technique to write a custom function. In this function, the seven arguments will be as follows:
This custom function will return the x-, y- and z-coordinates of the projectile's position in space as a single string that can be parsed into three separate values. Thus, even those who are not physics-savvy can write Liberty BASIC programs involving missiles, basketballs and expectorated watermelon seeds!
To obtain the source code for this function, go here.
Though I am partial to the Convert and Concatenate technique, there are at least three other ways in which functions can change the value of more than one variable used elsewhere in the program. Among the other ways are these:
dim pi(1) pi(1) = 3.14159
Thereafter, whenever a function needs the value of pi, all it has to do is reference the array value, pi(1).
I have no doubts that there are additional clever ways in which programmers have been using their creativity to get functions to peform feats of skill not originally imagined. If so, speak up in the Liberty BASIC Forum!
--- Tom Nally
::::::::::::::::::::::::::::::::::::::::::::::::::::
::::::::::::::::::::::::::::::::::::::::::::::::::::